/**
 * @file compare.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2025-05-06
 *
 * @copyright Copyright (c) 2025
 *
 */

#include "compare.h"
#include "xmzTypeDefine.h"
#include <math.h>

// 定义浮点数比较的误差范围
#define REAL_EPSILON 1e-6f   // Real (float) 误差
#define LREAL_EPSILON 1e-12 // LReal (double) 误差

// Byte 比较
Bool CompareByte(Bool pre, Byte val1, Byte val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0; // 无效操作
  }
}

// Word 比较
Bool CompareWord(Bool pre, Word val1, Word val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// DWord 比较
Bool CompareDWord(Bool pre, DWord val1, DWord val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// LWord 比较
Bool CompareLWord(Bool pre, LWord val1, LWord val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// SInt 比较
Bool CompareSInt(Bool pre, SInt val1, SInt val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// USInt 比较
Bool CompareUSInt(Bool pre, USInt val1, USInt val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// Int 比较
Bool CompareInt(Bool pre, Int val1, Int val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// UInt 比较
Bool CompareUInt(Bool pre, UInt val1, UInt val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// DInt 比较
Bool CompareDInt(Bool pre, DInt val1, DInt val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// UDInt 比较
Bool CompareUDInt(Bool pre, UDInt val1, UDInt val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// LInt 比较
Bool CompareLInt(Bool pre, LInt val1, LInt val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// ULInt 比较
Bool CompareULInt(Bool pre, ULInt val1, ULInt val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return val1 == val2;
  case CMP_NE:
    return val1 != val2;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2;
  case CMP_LE:
    return val1 <= val2;
  default:
    return 0;
  }
}

// Real 比较
Bool CompareReal(Bool pre, Real val1, Real val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return fabsf(val1 - val2) < REAL_EPSILON;
  case CMP_NE:
    return fabsf(val1 - val2) >= REAL_EPSILON;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2 || fabsf(val1 - val2) < REAL_EPSILON;
  case CMP_LE:
    return val1 <= val2 || fabsf(val1 - val2) < REAL_EPSILON;
  default:
    return 0;
  }
}

// LReal 比较
Bool CompareLReal(Bool pre, LReal val1, LReal val2, CompareOp op) {
  if (!pre) {
    return false;
  }
  switch (op) {
  case CMP_EQ:
    return fabsl(val1 - val2) < LREAL_EPSILON;
  case CMP_NE:
    return fabsl(val1 - val2) >= LREAL_EPSILON;
  case CMP_GT:
    return val1 > val2;
  case CMP_LT:
    return val1 < val2;
  case CMP_GE:
    return val1 >= val2 || fabsl(val1 - val2) < LREAL_EPSILON;
  case CMP_LE:
    return val1 <= val2 || fabsl(val1 - val2) < LREAL_EPSILON;
  default:
    return 0;
  }
}
// Byte 范围比较
Bool InRangeByte(Bool pre, Byte value, Byte min, Byte max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeByte(Bool pre, Byte value, Byte min, Byte max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// Word 范围比较
Bool InRangeWord(Bool pre, Word value, Word min, Word max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeWord(Bool pre, Word value, Word min, Word max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// DWord 范围比较
Bool InRangeDWord(Bool pre, DWord value, DWord min, DWord max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeDWord(Bool pre, DWord value, DWord min, DWord max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// LWord 范围比较
Bool InRangeLWord(Bool pre, LWord value, LWord min, LWord max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeLWord(Bool pre, LWord value, LWord min, LWord max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// SInt 范围比较

Bool InRangeSInt(Bool pre, SInt value, SInt min, SInt max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeSInt(Bool pre, SInt value, SInt min, SInt max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// USInt 范围比较
Bool InRangeUSInt(Bool pre, USInt value, USInt min, USInt max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeUSInt(Bool pre, USInt value, USInt min, USInt max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// Int 范围比较
Bool InRangeInt(Bool pre, Int value, Int min, Int max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeInt(Bool pre, Int value, Int min, Int max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// UInt 范围比较
Bool InRangeUInt(Bool pre, UInt value, UInt min, UInt max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeUInt(Bool pre, UInt value, UInt min, UInt max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// DInt 范围比较
Bool InRangeDInt(Bool pre, DInt value, DInt min, DInt max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeDInt(Bool pre, DInt value, DInt min, DInt max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// UDInt 范围比较
Bool InRangeUDInt(Bool pre, UDInt value, UDInt min, UDInt max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeUDInt(Bool pre, UDInt value, UDInt min, UDInt max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// LInt 范围比较
Bool InRangeLInt(Bool pre, LInt value, LInt min, LInt max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeLInt(Bool pre, LInt value, LInt min, LInt max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// ULInt 范围比较
Bool InRangeULInt(Bool pre, ULInt value, ULInt min, ULInt max) {
  if (!pre) {
    return false;
  }
  return value >= min && value <= max;
}
Bool OutOfRangeULInt(Bool pre, ULInt value, ULInt min, ULInt max) {
  if (!pre) {
    return false;
  }
  return value < min || value > max;
}

// Real 范围比较
Bool InRangeReal(Bool pre, Real value, Real min, Real max) {
  if (!pre) {
    return false;
  }
  return (value >= min || fabsf(value - min) < REAL_EPSILON) &&
         (value <= max || fabsf(value - max) < REAL_EPSILON);
}
Bool OutOfRangeReal(Bool pre, Real value, Real min, Real max) {
  if (!pre) {
    return false;
  }
  return (value < min && fabsf(value - min) >= REAL_EPSILON) ||
         (value > max && fabsf(value - max) >= REAL_EPSILON);
}

// LReal 范围比较
Bool InRangeLReal(Bool pre, LReal value, LReal min, LReal max) {
  if (!pre) {
    return false;
  }
  return (value >= min || fabsl(value - min) < LREAL_EPSILON) &&
         (value <= max || fabsl(value - max) < LREAL_EPSILON);
}
Bool OutOfRangeLReal(Bool pre, LReal value, LReal min, LReal max) {
  if (!pre) {
    return false;
  }
  return (value < min && fabsl(value - min) >= LREAL_EPSILON) ||
         (value > max && fabsl(value - max) >= LREAL_EPSILON);
}
